package protocol

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"

	HTTP "../../http"
	httpdata "../../httpdata"
	Key "../../key"

	"../../log"
)

// Log 全局日志
var Log = log.GetLog("library")

// Protocol GET/POST 协议
type Protocol struct {
	// 限制
	Key              *Key.Key
	UsingKey         bool // 使用 Key
	UsingToPrivilege bool // 使用 判断Privilege必须有权限 (Key必须生效)
	// 本地参数 (默认参数)
	Path   string // 匹配路径
	RegExp bool   // 正则匹配
	// 绑定目标 (自定义参数)
	Processor    func(w http.ResponseWriter, r *http.Request, v map[string]interface{})
	ProtocolType string // 协议类型 GET/POST 协议
}

// Routing 返回路由信息(默认参数)
func (P *Protocol) Routing() *HTTP.Routing {
	// 返回接口
	return &HTTP.Routing{
		Path:   P.Path,
		RegExp: P.RegExp,
	}
}

// ServeHTTP 缓存路由接口
func (P *Protocol) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// 判断协议
	if r.Method != P.ProtocolType {
		w.WriteHeader(http.StatusBadRequest)
		w.Write(httpdata.GetFound(http.StatusBadRequest))
		HTTP.Log.WarnS(fmt.Sprintf("异常协议访问[%s:%s]: %v\n", r.Method, P.ProtocolType, *r))
		return
	}
	// 转换输入参数
	mapResult := make(map[string]interface{})
	if r.Method == "GET" {
		r.ParseForm()
		// 转换参数
		for key, v := range r.Form {
			mapResult[key] = v
		}
	}
	if r.Method == "POST" {
		// 得到数据
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			Log.ErrorS(fmt.Sprintf("read body err, %v\n", err))
			return
		}
		// 格式化参数
		if len(body) > 0 {
			err = json.Unmarshal(body, &mapResult)
			if err != nil {
				Log.ErrorS(fmt.Sprintf("JsonToMapDemo err:  %v\n", err))
			}
		}
	}
	// 判断访问
	if P.Processor != nil {
		// 判断访问
		if P.UsingKey {
			// 判断 Key
			R, ok := P.Key.IfKey(mapResult, "Key")
			if !ok {
				w.WriteHeader(http.StatusUnauthorized)
				return
			}
			// 判断是否启用特权访问
			if P.UsingToPrivilege {
				// 判断是否有特权
				if !R.GetPrivilege(P.Path) {
					w.WriteHeader(http.StatusUnauthorized)
					return
				}
			}
		}
		P.Processor(w, r, mapResult)
	} else {
		w.WriteHeader(http.StatusNotImplemented)
		w.Write(httpdata.GetFound(http.StatusNotImplemented))
		HTTP.Log.WarnS(fmt.Sprintf("系统异常路由无处理实现: %v\n", *r))
	}
}
